﻿using Kingdee.BOS;
using Kingdee.BOS.Authentication;
using Kingdee.BOS.Performance.Common;
using Kingdee.BOS.ServiceHelper;
using Kingdee.BOS.Util;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace KingdeeWebServiceProject
{
    internal class LogDataCenterForWebService
    {
        static Dictionary<string, Context> UserTokenMapContext;

        /// <summary>
        /// 使用给定的用户名和密码登录指定的数据中心
        /// </summary>
        /// <param name="dataCenterID">数据中心ID</param>
        /// <param name="userName">登录用户名</param>
        /// <param name="password">登录密码</param>
        /// <param name="userToken">用户令牌，用于已登录过的用户获取登录上下文</param>
        /// <param name="ctx">登录上下文</param>
        /// <returns>返回JSON对象，包含登录结果、用户令牌、返回消息等信息</returns>
        internal JObject Auth(string dataCenterID, string userName, string password, string userToken, out Context ctx)
        {
            var result = new JObject();
            result.Add("Result", false);
            result.Add("UserToken", "");
            result.Add("Message", "");
            if (UserTokenMapContext == null)
            {
                UserTokenMapContext = new Dictionary<string, Context>();
            }
            else
            {
                if (!string.IsNullOrWhiteSpace(userToken) && UserTokenMapContext.TryGetValue(userToken, out ctx) && ctx != null)
                {
                    result["Result"] = true;
                    result["UserToken"] = userToken;
                    result["Message"] = "获取用户登录上下文成功";
                    return result;
                }
            }
            if (string.IsNullOrWhiteSpace(dataCenterID))
            {
                dataCenterID = this.GetDataCenterId();
                if (string.IsNullOrEmpty(dataCenterID))
                {
                    result["Message"] = "您传入的数据中心ID为空，并且未能获取到允许WebService登录的数据中心，请联系K3Cloud管理员！";
                    ctx = null;
                    return result;
                }
            }

            var loginInfo = new LoginInfo()
            {
                AcctID = dataCenterID,
                AuthenticateType = AuthenticationType.PwdAuthentication,
                Username = userName,
                Password = ConfidentialDataSecurityUtil.CipherText(password),
                Lcid = 2052,
                LoginType = LoginType.NormalERPLogin
            };

            var ret = LoginServiceHelper.Login(PerformanceContext.Create(PerfArgsCollectionType.CallDirectly), "", loginInfo);
            if (ret.LoginResultType == LoginResultType.Success)
            {
                result["Result"] = true;
                result["UserToken"] = ret.Context.UserToken;
                result["Message"] = ret.Message;
                ctx = ret.Context;
                if (UserTokenMapContext.Count >= 200)
                {
                    UserTokenMapContext.Remove(UserTokenMapContext.Keys.First());
                }
                UserTokenMapContext[ret.Context.UserToken] = ret.Context;
            }
            else
            {
                ctx = ret.Context;
                result["Message"] = ret.Message;
            }
            return result;
        }

        /// <summary>
        /// 使用给定的用户名和密码和语言ID登录指定的数据中心
        /// </summary>
        /// <param name="dataCenterID">数据中心ID</param>
        /// <param name="userName">登录用户名</param>
        /// <param name="password">登录密码</param>
        /// <param name="strLocaleID">语言ID</param>
        /// <param name="userToken">用户令牌，用于已登录过的用户获取登录上下文</param>
        /// <param name="ctx">登录上下文</param>
        /// <returns>返回JSON对象，包含登录结果、用户令牌、返回消息等信息</returns>
        internal JObject Auth(string dataCenterID, string userName, string password, string strLocaleID, string userToken, out Context ctx)
        {
            var result = new JObject();
            result.Add("Result", false);
            result.Add("UserToken", "");
            result.Add("Message", "");
            if (UserTokenMapContext == null)
            {
                UserTokenMapContext = new Dictionary<string, Context>();
            }
            else
            {
                if (!string.IsNullOrWhiteSpace(userToken) && UserTokenMapContext.TryGetValue(userToken, out ctx) && ctx != null)
                {
                    result["Result"] = true;
                    result["UserToken"] = userToken;
                    result["Message"] = "获取用户登录上下文成功";
                    return result;
                }
            }
            if (string.IsNullOrWhiteSpace(dataCenterID))
            {
                dataCenterID = this.GetDataCenterId();
                if (string.IsNullOrEmpty(dataCenterID))
                {
                    result["Message"] = "您传入的数据中心ID为空，并且未能获取到允许WebService登录的数据中心，请联系K3Cloud管理员！";
                    ctx = null;
                    return result;
                }
            }

            var loginInfo = new LoginInfo()
            {
                AcctID = dataCenterID,
                AuthenticateType = AuthenticationType.PwdAuthentication,
                Username = userName,
                Password = ConfidentialDataSecurityUtil.CipherText(password),
                Lcid = Convert.ToInt32(strLocaleID),
                LoginType = LoginType.NormalERPLogin
            };
            var ret = LoginServiceHelper.Login(PerformanceContext.Create(PerfArgsCollectionType.CallDirectly), "", loginInfo);
            if (ret.LoginResultType == LoginResultType.Success)
            {
                result["Result"] = true;
                result["UserToken"] = ret.Context.UserToken;
                result["Message"] = ret.Message;
                ctx = ret.Context;
                if (UserTokenMapContext.Count >= 200)
                {
                    UserTokenMapContext.Remove(UserTokenMapContext.Keys.First());
                }
                UserTokenMapContext[ret.Context.UserToken] = ret.Context;
            }
            else
            {
                ctx = ret.Context;
                result["Message"] = ret.Message;
            }
            return result;
        }

        /// <summary>
        /// 根据用户令牌获取缓存的用户登录上下文
        /// </summary>
        /// <param name="userToken">用户令牌</param>
        /// <param name="ctx">out参数，返回用户登录上下文</param>
        /// <returns>返回获取结果与返回消息</returns>
        internal JObject GetLogContextFromCache(string userToken, out Context ctx)
        {
            ctx = null;

            var result = new JObject();
            result.Add("Result", false);
            result.Add("Message", "");

            if (UserTokenMapContext == null)
            {
                result["Message"] = "用户登录上下文缓存不存在";
                return result;
            }

            if (string.IsNullOrEmpty(userToken))
            {
                result["Message"] = "给定的用户令牌不可为空";
                return result;
            }

            UserTokenMapContext.TryGetValue(userToken, out ctx);
            if (ctx == null)
            {
                result["Message"] = "给定的用户令牌无效";
                return result;
            }
            result["Result"] = true;
            return result;
        }

        /// <summary>
        /// 清除Webservice登陆信息缓存
        /// </summary>
        internal void ClearWebServiceLogCache()
        {
            if (UserTokenMapContext != null)
            {
                UserTokenMapContext.Clear();
            }
        }

        /// <summary>
        /// 获取发布WebService的数据中心Id
        /// </summary>
        private string GetDataCenterId()
        {
            string dataCenterId = "";
            var key = "CMKWebServiceFromDataCenter";
            if (KDConfiguration.Current.CommonConfiguration.AppSettings.Settings.AllKeys.Contains(key))
            {
                dataCenterId = KDConfiguration.Current.CommonConfiguration.AppSettings.Settings[key].Value;
            }
            if (string.IsNullOrWhiteSpace(dataCenterId))
            {
                if (KDConfiguration.Current.PackageConfigurations["winshan_ri"].AppSettings.Settings.AllKeys.Contains(key))
                {
                    dataCenterId = KDConfiguration.Current.PackageConfigurations["winshan_ri"].AppSettings.Settings[key].Value;
                }
            }
            return dataCenterId;
        }
    }
}
